<script setup lang="ts">
import { requiredCheck, singleIpCheckFun, validatePortFun } from "@/utils/verify";
import { ref } from "vue";

interface Props {
  title?: string;
  rowData?: Object;
  links?: Object;
  lanIfid?: Array;
  ifid?: Object;
  isLan: Boolean;
  isAutoHeight: Boolean;
}

const props = withDefaults(defineProps<Props>(), {
  title: "新增节点",
  rowData: undefined,
  ifid: undefined,
  links: [],
  isLan: false,
  lanIfid: [],
  isAutoHeight: false,
  isDynamicIp: false,
  isDynamicPort: false
});
defineOptions({
  name: "UpdateForm" // 默认策略
});
import useUpdate from "@/hooks/useUpdate";
import { ifaceAll, ifacemodeUpdate } from "@/api/modules/dynamic-camouflage/line-config";
import { addData, editData, ifaceAttrIpList, ifaceSentryEdit } from "@/api/modules/dynamic-camouflage/sentinel-config";
import { getIpRange, setIpRange } from "@/utils";

const getIpRangeCount = value => {
  /**
   * 将IP地址转换为整数
   * @param {string} ip - IP地址，如"192.168.1.1"
   * @returns {number} 转换后的整数
   */
  function ipToInt(ip) {
    return (
      ip.split(".").reduce((acc, octet) => {
        return (acc << 8) + parseInt(octet, 10);
      }, 0) >>> 0
    ); // 使用无符号右移确保结果为正数
  }

  /**
   * 计算IP段中包含的IP个数
   * @param {string} ipRange - IP段，格式如"192.168.33.32-192.168.39.32"
   * @returns {number} IP个数，如果格式错误则返回-1
   */
  function countIpInRange(ipRange) {
    if (!ipRange) {
      return 0;
    }
    if (!ipRange || !ipRange.includes("-")) {
      return 0;
    }
    // 验证输入格式
    const ipRangeRegex = /^(\d{1,3}\.){3}\d{1,3}-(\d{1,3}\.){3}\d{1,3}$/;
    if (!ipRangeRegex.test(ipRange)) {
      console.error('无效的IP段格式，请使用"xxx.xxx.xxx.xxx-xxx.xxx.xxx.xxx"格式');
      return -1;
    }

    // 分割起始IP和结束IP
    const [startIp, endIp] = ipRange.split("-");

    // 验证每个IP的每个段是否在有效范围内
    const validateOctet = octet => {
      const num = parseInt(octet, 10);
      return !isNaN(num) && num >= 0 && num <= 255;
    };

    const startOctets = startIp.split(".");
    const endOctets = endIp.split(".");

    if (startOctets.length !== 4 || endOctets.length !== 4) {
      console.error("无效的IP地址");
      return -1;
    }

    if (!startOctets.every(validateOctet) || !endOctets.every(validateOctet)) {
      console.error("IP地址中的数字必须在0-255之间");
      return -1;
    }

    // 转换为整数并计算差值
    const startInt = ipToInt(startIp);
    const endInt = ipToInt(endIp);

    if (startInt > endInt) {
      console.error("起始IP不能大于结束IP");
      return -1;
    }

    // 计算IP个数（包含起始和结束IP）
    return endInt - startInt + 1;
  }

  return countIpInRange(value);
};

const getIpCidrCount = value => {
  /**
   * 验证IP地址是否有效
   * @param {string} ip - IP地址，如"192.168.33.0"
   * @returns {boolean} 是否有效的IP地址
   */
  function isValidIp(ip) {
    const octets = ip.split(".");
    if (octets.length !== 4) return false;

    return octets.every(octet => {
      const num = parseInt(octet, 10);
      return !isNaN(num) && num >= 0 && num <= 255 && octet === num.toString();
    });
  }

  /**
   * 计算CIDR格式IP段包含的IP个数
   * @param {string} cidr - CIDR格式的IP段，如"192.168.33.0/24"
   * @returns {number} IP个数，如果格式错误则返回-1
   */
  function countIpInCidr(cidr) {
    if (!cidr) {
      return 0;
    }
    if (!cidr || !cidr.includes("/")) {
      return 0;
    }
    // 验证CIDR格式
    const cidrRegex = /^(\d{1,3}\.){3}\d{1,3}\/\d{1,2}$/;
    if (!cidrRegex.test(cidr)) {
      console.error('无效的CIDR格式，请使用"xxx.xxx.xxx.xxx/xx"格式');
      return -1;
    }

    // 分割IP地址和前缀长度
    const [ip, prefixStr] = cidr.split("/");
    const prefix = parseInt(prefixStr, 10);

    // 验证前缀长度是否有效
    if (isNaN(prefix) || prefix < 0 || prefix > 32) {
      console.error("前缀长度必须在0-32之间");
      return -1;
    }

    // 验证IP地址是否有效
    if (!isValidIp(ip)) {
      console.error("无效的IP地址");
      return -1;
    }

    // 计算IP数量：CIDR中可用IP数为2^(32-前缀长度)
    // 注意：这里计算的是总地址数，包括网络地址和广播地址
    return Math.pow(2, 32 - prefix);
  }

  return countIpInCidr(value);
};
const emits = defineEmits(["success"]);
const { updateFormData, updateFormRef, updateFormRules, submit, showHandle, openHandle, closeHandle } = useUpdate({
  rules: {
    ifid: [...requiredCheck("请选择线路")],
    name: [...requiredCheck("请输入分组名称")],
    vlanid: [
      {
        validator: (rule, value, callback) => {
          if (!updateFormData.showVlan) {
            callback();
          } else {
            if (!value) {
              callback(new Error("请输入Vlan"));
            } else {
              callback();
            }
          }
        },
        trigger: "blur"
      }
    ],
    interval: [...requiredCheck("请输入频率")],
    lowport_interval: [...requiredCheck("请输入频率")],
    percent: [...requiredCheck("请输入限定概率")],
    ip: [...requiredCheck("请选择网关")],
    iprange: [
      ...requiredCheck("请输入IP"),
      {
        validator: (rule, value, callback) => {
          const testOne =
            /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\/(3[0-2]|[12]?[0-9])$/;
          const rangeRegex =
            /^((25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)\.){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)-((25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)\.){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)$/;

          if (value && value?.includes("-") && !value?.startsWith("-")) {
            console.log("rangeRegex.test(value)::", rangeRegex.test(value));
            const ipOne = value.split("-")[0];
            let ipTwo = value.split("-")[1];
            if (!isNaN(Number(ipTwo))) {
              let arr = ipOne.split(".");
              if (arr.length != 4) {
                console.log("aaaa");
                callback(new Error("IP格式错误"));
              }
              ipTwo = `${arr[0]}.${arr[1]}.${arr[2]}.${ipTwo}`;
            }

            function ipToInt(ip) {
              return ip.split(".").reduce((acc, octet) => (acc << 8) + parseInt(octet, 10), 0);
            }

            let data = `${value.split("-")[0]}-${ipTwo}`;

            console.log("getIpRangeCount(value)", getIpRangeCount(data));
            console.log("data::", data);
            if (getIpRangeCount(data) > 10000) {
              callback(new Error("IP数量不能超过10000"));
            }
            if (rangeRegex.test(data) && ipToInt(ipOne) <= ipToInt(ipTwo)) {
              callback();
            } else {
              callback(new Error("IP格式错误"));
            }
          }
          if (value && value?.includes("/")) {
            if (getIpCidrCount(value) > 10000) {
              callback(new Error("IP数量不能超过10000"));
            }
            if (testOne.test(value)) {
              callback();
            } else {
              callback(new Error("IP格式错误"));
            }
          }
          // if (value && value?.includes(";")) {
          //   if (value?.endsWith(";")) {
          //     callback(new Error("IP格式错误"));
          //   }
          //   let arr = value.split(";");
          //   let pass = true;
          //   for (let i = 0; i < arr.length; i++) {
          //     if (!singleIpCheckFun(arr[i])) {
          //       pass = false;
          //     }
          //   }
          //   if (pass) {
          //     callback();
          //   } else {
          //     callback(new Error("IP格式错误"));
          //   }
          // }
          if (singleIpCheckFun(value)) {
            callback();
          } else {
            callback(new Error("IP格式错误"));
          }
        }
      }
    ],
    destport: [
      ...requiredCheck("请输入端口"),
      {
        validator: (rule, value, callback) => {
          if (value?.includes(";") && !value?.startsWith(";")) {
            const ports = value.split(";");
            const pass = ports.every(port => validatePortFun(port));
            if (pass) {
              callback();
            } else {
              callback("端口格式错误");
            }
          }
          if (value?.includes("-") && !value?.startsWith("-") && !value?.endsWith("-")) {
            const ports = value.split("-");
            let startPort = ports[0];
            let endPort = ports[1];
            const pass = ports.every(port => validatePortFun(port));
            if (pass && Number(startPort) < Number(endPort)) {
              callback();
            } else {
              callback("端口格式错误");
            }
          }
          if (validatePortFun(value)) {
            callback();
          } else {
            callback("端口格式错误");
          }
        }
      }
    ]
  },
  defaultData: {
    type: "1",
    destport: "",
    percent: 50,
    showVlan: true,
    proto: "0"
  }
});

async function submitCb() {
  let ifid = updateFormData.ifid;
  let id = props.lanIfid.includes(updateFormData.ifid) ? updateFormData?.ip : updateFormData?.id;
  const data = props.links.find(item => item.ifid === updateFormData.ifid);
  let cfg = {
    percent: 50,
    interval: 0,
    lowport_interval: 0,
    lowport_percent: 50
  };
  if (updateFormData.isDynamicIp) {
    cfg.interval = updateFormData.interval;
  }
  if (updateFormData.isDynamicPort) {
    cfg.lowport_interval = updateFormData.lowport_interval;
  }
  await submit({
    addApi: props.lanIfid.includes(updateFormData.ifid) ? editData : addData,
    updateApi: editData,
    sendData: {
      destport: updateFormData.destport,
      ifid: updateFormData.ifid,
      iprange: getIpRange(updateFormData.iprange),
      name: data?.name,
      type: updateFormData.isDynamicIp ? "2" : "1",
      vlanid: !updateFormData.showVlan ? "0" : String(updateFormData.vlanid),
      cfg: JSON.stringify(cfg),
      id: id
    }
  });
  emits("success", ifid);
}

async function openCb() {
  openHandle({
    row: {
      ...props.rowData,
      iprange: props.rowData?.iprange ? setIpRange(props.rowData?.iprange) : undefined
    },
    id: props.rowData?.id
  });
  if (props.ifid) {
    updateFormData.ifid = props.ifid;
  }
  // if (updateFormData?.id) {
  // }
  updateFormData.showVlan = Boolean(Number(updateFormData.vlanid || 0));

  await getAttr();
  getIfaceSentryEdit();
}

const ipAttr = ref([]);

async function getAttr() {
  const res = await ifaceAttrIpList({
    ifid: props.ifid
  });
  console.log(res);
  ipAttr.value = res.data.splice(0, 500);
}

async function selectGetAttr() {
  const res = await ifaceAttrIpList({
    ifid: updateFormData.ifid
  });
  console.log(res);
  ipAttr.value = res.data.splice(0, 500);
}

async function getIfaceSentryEdit() {
  if (!props.rowData?.id) return;
  const res = await ifaceSentryEdit({
    id: props.rowData?.id
  });
  if (props.isLan) {
    updateFormData.ip = res.id;
    console.log(res);
    if (!ipAttr.value.some(item => item.id === res.id)) {
      ipAttr.value.push({
        id: res.id,
        vdyn: res.ip
      });
    }
  }
  if (res.type == 2) {
    const cfg = JSON.parse(res.cfg);
    updateFormData.interval = cfg.interval;
    updateFormData.percent = cfg.percent;
    updateFormData.isDynamicIp = true;
  }
  if (res.cfg) {
    const cfg = JSON.parse(res.cfg);
    updateFormData.lowport_interval = cfg.lowport_interval;
    updateFormData.lowport_percent = cfg.lowport_percent;
    updateFormData.isDynamicPort = Number(cfg.lowport_interval) > 0;
  }
}
</script>

<template>
  <div class="update-form mg-l-sm update-form-edit" style="display: inline-block; height: 55px" @click="openCb">
    <slot>
      <el-button class="mg-l-sm" type="primary">新增</el-button>
    </slot>
  </div>
  <base-dialog @confirm="submitCb()" width="800px" :title="title" v-model="showHandle">
    <div class="details">
      <div class="details-main">
        <el-form ref="updateFormRef" :model="updateFormData" :rules="updateFormRules" label-width="80px" label-suffix="：">
          <div class="h-box">
            <el-form-item label-width="120px" label="线路" prop="ifid">
              <el-select @change="selectGetAttr" :disabled="updateFormData?.id" style="width: 90px" v-model="updateFormData.ifid">
                <el-option
                  v-for="item in links.filter(i => !i.name.includes('WAN'))"
                  :key="item.ifid"
                  :value="item.ifid"
                  :label="item.label"
                ></el-option>
              </el-select>
            </el-form-item>
            <el-form-item
              class="my-form-item h-box"
              :class="!updateFormData.showVlan ? 'hide-err' : ''"
              label=""
              label-width=""
              prop="vlanid"
            >
              <div class="h-box">
                <el-checkbox v-model="updateFormData.showVlan" label="Vlan"></el-checkbox>
                <el-input-number
                  :min="1"
                  :max="4094"
                  v-if="updateFormData.showVlan"
                  class="mg-l-sm"
                  style="width: 150px"
                  v-model="updateFormData.vlanid"
                  placeholder="请输入"
                ></el-input-number>
              </div>
            </el-form-item>
            <el-form-item class="gate" label-width="120px" label="网关" prop="ip" v-if="lanIfid.includes(updateFormData.ifid)">
              <el-select :disabled="updateFormData?.id" style="width: 150px; border-color: #03ed03" v-model="updateFormData.ip">
                <el-option v-for="item in ipAttr" :key="item.id" :value="item.id" :label="item.ip.replace('/24', '')"></el-option>
              </el-select>
            </el-form-item>
          </div>
          <template v-if="false">
            <el-divider style="width: calc(100% - 40px); margin: 15px auto" />
            <div class="h-box">
              <el-form-item label-width="120px" label="类型" prop="type">
                <el-radio-group v-model="updateFormData.type">
                  <el-radio value="1" label="静态"></el-radio>
                  <el-radio value="2" label="动态"></el-radio>
                </el-radio-group>
              </el-form-item>
              <div class="h-box mg-l-sm" v-if="updateFormData.type == 2">
                <el-form-item label="频率" label-width="70px" prop="interval">
                  <el-input-number v-model="updateFormData.interval" style="width: 120px" />
                  <span>分钟</span>
                </el-form-item>
              </div>
              <div class="h-box" v-if="false && updateFormData.type == 2">
                <el-form-item label="限定概率" label-width="100px" prop="percent">
                  <el-input-number v-model="updateFormData.percent" style="width: 120px" />

                  <span>%</span>
                </el-form-item>
              </div>
            </div>
          </template>
          <el-divider style="width: calc(100% - 40px); margin: 15px auto" />
          <div class="h-box mg-t-sm">
            <el-form-item class="cur-item" style="width: 150px">
              <el-checkbox v-model="updateFormData.isDynamicIp" label="动态IP"></el-checkbox>
            </el-form-item>
            <el-form-item label="IP地址" label-width="100px" prop="iprange">
              <el-input style="width: 180px" v-model="updateFormData.iprange" placeholder="请输入IP地址"></el-input>
            </el-form-item>
            <el-form-item v-if="updateFormData.isDynamicIp" label="变换频率" label-width="120px" prop="interval">
              <el-input-number :min="1" v-model="updateFormData.interval" style="width: 120px" />
              <span>分钟</span>
            </el-form-item>
          </div>

          <el-divider style="width: calc(100% - 40px); margin: 15px auto" />
          <div class="h-box mg-t-sm">
            <el-form-item class="cur-item"  style="width: 150px">
              <el-checkbox v-model="updateFormData.isDynamicPort" label="动态端口"></el-checkbox>
            </el-form-item>
            <el-form-item  label="端口" label-width="100px" prop="destport">
              <el-input style="width: 180px" v-model="updateFormData.destport" placeholder="请输入端口"></el-input>
            </el-form-item>
            <el-form-item v-if="updateFormData.isDynamicPort" label="变换频率" label-width="120px" prop="lowport_interval">
              <el-input-number :min="1" v-model="updateFormData.lowport_interval" style="width: 120px" />
              <span>分钟</span>
            </el-form-item>
          </div>
        </el-form>
      </div>
    </div>
    <template #footer-more-button></template>
  </base-dialog>
</template>

<style lang="scss" scoped>
.update-form {
  display: inline-block;
}

.gate {
  :deep(.el-form-item__label) {
    color: #03ed03;
  }

  :deep(.el-select__wrapper) {
    box-shadow: 0 0 0 1px #03ed03 inset;
  }

  :deep(.el-select__placeholder) {
    color: #03ed03;
  }
}

.my-form-item {
  :deep(.el-form-item__error) {
    margin-left: 57px !important;
  }
}

.hide-err {
  :deep(.el-form-item__error) {
    display: none !important;
  }
}

.cur-item {
  :deep(.el-form-item__content) {
    margin-left: 58px !important;
  }
}
</style>
